home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
429_01
/
chess12
/
chess.hpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-29
|
9KB
|
307 lines
#if !defined(CHESS_HPP)
#define CHESS_HPP
#include "misc.hpp"
#include "brdsize.hpp"
enum PIECECOLOR { WHITE, BLACK };
inline PIECECOLOR OtherColor(PIECECOLOR c)
{ return(c == WHITE ? BLACK : WHITE); }
enum PIECETYPE { TYPEKING, TYPEQUEEN, TYPEBISHOP, TYPEKNIGHT,
TYPEROOK, TYPEPAWN, TYPENOPIECE };
// simple completion status of a move
enum MOVEEVAL
{
// move done (not an en passant capture)
MOVEDONE,
// en passant capture move performed
MOVEENPASSANT,
// move not performed because it is illegal
ILLEGALMOVE,
// move not performed because if would allow opponent to take
// king on next move
WOULDLOSEKING
};
// full completion status of move
class MOVESTATUS
{
public:
// simple completions status
MOVEEVAL status;
// if status is WOULDLOSEKING, dangerToKing specifies the position
// of the opponent piece that would take the king on the nex move
POSITION dangerToKing;
MOVESTATUS(void) { };
// constructor if status is not WOULDLOSEKING
MOVESTATUS(MOVEEVAL s) : status(s) { };
// constructor if status is WOULDLOSEKING
MOVESTATUS(MOVEEVAL s, POSITION p) : status(s), dangerToKing(p) { };
};
// specifies a move
enum MOVETYPE { KINGSIDECASTLE, QUEENSIDECASTLE, NORMALMOVE };
class PIECEMOVE
{
public:
MOVETYPE type;
POSITION start, end;
// if moved piece is pawn which has thus arrived last rank, the
// type of the piece to promote it to. set to TYPENOPIECE if no
// promotion.
PIECETYPE promoteType;
PIECEMOVE(void) { }
PIECEMOVE
(
MOVETYPE t,
POSITION s,
POSITION e,
PIECETYPE pT = TYPENOPIECE
) : type(t), start(s), end(e), promoteType(pT) { }
// constructor for castling moves
PIECEMOVE
(
MOVETYPE t
) : type(t) { }
};
class PIECE;
// records whether the current move is an en passant capture, or
// follows a two-rank move of a pawn
enum EFFECTENPASSANT { ENPASSANTCAPTURE, AFTERDOUBLEMOVE, OTHERMOVE };
// information (other than the starting and end piece position)
// required to undo the effects of moving a piece
class MOVEUNDODATA
{
public:
// if not null, piece captured by moving piece
PIECE *capturedPiece;
// en passant effect
EFFECTENPASSANT enPassantEffect;
// if enPassantEffect not OTHERMOVE, records position of
// previously double-moved pawn
POSITION saveDoubleMoved;
};
// evalution of change in relative situation of the two players after
// one or more moves
enum SITUATIONOFKING { KINGLOST, STALEMATE, KINGOK };
class BOARDMETRIC
{
public:
SITUATIONOFKING kingSituation[2]; // indexed by PIECECOLOR
// change in relative material (total white material -
// total black material)
int materialDiff;
};
// maximum number of pieces of one color on the board
const int MAXPIECES = 16;
// maximum number of locations that a piece can reach in
// a single move
const int MAXMOVES = 28;
// list of moves which result in the greatest gain (or least loss)
// of material.
class BESTMOVES
{
public:
// number of moves in list
int nMoves;
PIECEMOVE move[MAXPIECES * MAXMOVES];
};
// internal representation of chess board
class BOARD
{
private:
// location in brd array points to piece in corresponding position
// on chess board. a null pointer means no piece in that location.
PIECE *brd[NUMROWS][NUMCOLS];
// flags if the last move was a double pawn move
BOOL wasLastMoveDoublePawn;
// if last move was double pawn move, contains the ending position
// of the pawn.
POSITION doubleMovedPawn;
// recursive function to find optimal moves in terms of
// getting opponent in checkmate or material gain.
void helpFindBestMoves
(
// number of moves to look-ahead
int lookAhead,
// color of player that is going to move
PIECECOLOR moveColor,
// metric of optimal moves
BOARDMETRIC &metric,
// if not null, filled in with list of optimal moves
BESTMOVES *bestMoves
);
public:
BOARD(void);
~BOARD(void);
PIECE *whatPiece(POSITION p) const
{ return(brd[p.row][p.col]); }
PIECE *whatPiece(int row, int col) const
{ return(brd[row][col]); }
// perform a move. move is not validated (assumed to be legal).
void doMove
(
// starting and ending position of piece to move
POSITION start,
POSITION end,
// data needed to undo move. caller must delete captured
// piece (unless move is undone)
MOVEUNDODATA &undoData
);
// undo a move done with doMove
void undoMove
(
// ending and original position of piece (transposed of order
// as passed to doMove)
POSITION end,
POSITION orig,
// undo data returned by call to doMove
MOVEUNDODATA undoData
);
// returns TRUE if the king of the given color can castle on the
// given side (as given by whichCastle). the one preventing
// condition not cheched for is if the final position of the king
// places it in check.
BOOL canCastle(MOVETYPE whichCastle, PIECECOLOR color);
// do a castle on the given side with the king of given color.
// no validation, assumed to be legal.
void castle(MOVETYPE whichCastle, PIECECOLOR color,
MOVEUNDODATA &undoData);
// undo a castle. undoData must be as returned by castle member.
void undoCastle(MOVETYPE whichCastle, PIECECOLOR color,
MOVEUNDODATA &undoData);
// checks if the piece in the given position can be promoted.
BOOL canPromote(POSITION where);
// promotes pawn in given location to piece of given type.
// assumed to be legal, no validation.
void promote(POSITION where, PIECETYPE promoteType);
// "un-promotes" a piece back to being a pawn. won't work if
// the piece was not originally a pawn.
void restorePawn(POSITION where);
// do a move with full validation, returning status
MOVESTATUS doUserMove
(
// starting and ending position of piece. the starting
// position is assumed to be valid.
POSITION start,
POSITION end
);
// complete check of whether a castle move can be done
BOOL userCanCastle(MOVETYPE whichCastle, PIECECOLOR color);
// returns TRUE if the last move was a double pawn move. if
// TRUE, the ending position of the pawn is returned as well.
BOOL lastMoveDoublePawn(POSITION &whereDoubleMovedPawn) const
{
if (wasLastMoveDoublePawn)
whereDoubleMovedPawn = doubleMovedPawn;
return(wasLastMoveDoublePawn);
}
// front end for helpFindBestMoves. simply initializes the
// material change to 0.
void findBestMoves
(
int lookAhead,
PIECECOLOR moveColor,
BOARDMETRIC &metric,
BESTMOVES *bestMoves
)
{
metric.materialDiff = 0;
helpFindBestMoves(lookAhead, moveColor, metric, bestMoves);
return;
}
};
// list of possible ending positions if a piece is moved from a fixed
// starting positions
class POSITIONLIST
{
public:
// number of ending positions
int nMoves;
POSITION end[MAXMOVES];
};
// abstract base class for piece.
class PIECE
{
private:
const PIECECOLOR color;
const PIECETYPE type;
// material value of piece.
const int value;
// number of moves piece has made.
int moveCount;
public:
PIECE(PIECECOLOR c, PIECETYPE t, int v) :
color(c), type(t), value(v), moveCount(0)
{ }
virtual ~PIECE(void) { }
PIECECOLOR whatColor(void) const { return(color); }
virtual PIECETYPE whatType(void) const { return(type); }
virtual int whatValue(void) const { return(value); }
// material value of piece where white is positive and
// black is negative
int signedValue(void) const
{ return(color == WHITE ? whatValue() : -whatValue()); }
// tell piece it was m